#include "widget.h"
#include "ui_widget.h"
#include <QLCDNumber>
#include <QTimer>
#include <QDebug>
#include <QObject>


void QLCDNumberCountDown(Ui::Widget* ui, Widget* Pthis, QTimer* timer) {
    //设置初始值
    ui->lcdNumber->display(10);

    //把QTimer的timeout信号和咱们自己的槽函数进行连接
    QObject::connect(timer, &QTimer::timeout, Pthis, &Widget::handle);

    //启动定时器，参数是触发timeout 的周期。单位是 ms
    timer->start(1000);

    //如果直接在 Widget 构造函数中, 通过一个循环 + sleep 的方式是否可以呢?
    //显然, 这个代码是不行的. 循环会使 Widget 的构造函数无法执行完毕, 此时界面是不能正确构造和显示的

    //上述代码如果是在 Widget 构造函数中, 另起一个线程, 在新线程中完成 循环 + sleep 是否可以呢?
    //这个代码同样是不行的. Qt 中规定, 任何对于 GUI 上内容的操作, 必须在 主线程 中完成. 像 Widget 构造函数, 以及 connect 连接的 slot 函数, 都是在主线程中调用的
    //而我们自己创建的线程则不是
    //当我们自己的线程中尝试对界面元素进行修改时, Qt 程序往往会直接崩溃
    //这样的约定主要是因为 GUI 中的状态往往是牵一发动全身的, 修改一个地方, 就需要同步的对其他内容进行调整
    //比如调整了某个元素的尺寸, 就可能影响到内部的文字位置, 或者其他元素的位置. 这里一连串的修改
    //都是需要按照一定的顺序来完成的由于多线程执行的顺序无法保障, 因此 Qt 从根本上禁止了其他线程修改 GUI 状态, 避免后续的一系列问题

    //如果我们也有类似的需要 "周期性修改界面状态" 的需求, 也需要优先考虑使用定时器
}

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //创建一个QTimer实例
    Widget::timer = new QTimer(this);
    QLCDNumberCountDown(ui, this, Widget::timer);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::handle()
{
    //拿到LCDNumber中的数字
    int value = ui->lcdNumber->intValue();
    if (value <= 0) {
        timer->stop();
        return;
    }
    ui->lcdNumber->display(value - 1);
}

